﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DesignPanel;
using System.Collections;
using System.ComponentModel.Design;
using System.Drawing.Design;
using DesignPanel.Service;
using System.Xml;

namespace UIDesigner
{
    public partial class UIDesigner : Form
    {
        TreeNodeEx m_theRootNode = new TreeNodeEx("Component", 0, 0);
        ImageManager m_theImageMgr = new ImageManager();
        ContextMenu m_theMainContextMenu = null;

        public UIDesigner()
        {
            InitializeComponent();
            Init();
            m_theImageMgr.Init(this.imageList_tree);
            theTreeView.ItemHeight = 20;
        }

        private void UIDesigner_Load(object sender, EventArgs e)
        {
            theTabCtrl.Focus();
            // 启动的时候默认追加一个 Form
            AddDesigner(FormDesigner.DesignType.Form, "Form Demo");
        }

        /// <summary>
        /// 初始化工具栏
        /// </summary>
        private void Init()
        {
            theToolBoxCtrl.AddItem(typeof(Button));
            theToolBoxCtrl.AddItem(typeof(Label));
            theToolBoxCtrl.AddItem(typeof(LinkLabel));
            theToolBoxCtrl.AddItem(typeof(CheckBox));
            theToolBoxCtrl.AddItem(typeof(TextBox));
            theToolBoxCtrl.AddItem(typeof(RadioButton));
            theToolBoxCtrl.AddItem(typeof(ComboBox));
            theToolBoxCtrl.AddItem(typeof(PictureBox));
            theToolBoxCtrl.AddItem(typeof(ListBox));
            theToolBoxCtrl.AddItem(typeof(ListView));
            theToolBoxCtrl.AddItem(typeof(Panel));
            theToolBoxCtrl.AddItem(typeof(GroupBox));
            theToolBoxCtrl.AddItem(typeof(TabControl));
            theToolBoxCtrl.AddItem(typeof(Splitter));
            theToolBoxCtrl.AddItem(typeof(UILine));
            theToolBoxCtrl.AddItem(typeof(NumericUpDown));
            theToolBoxCtrl.AddItem(typeof(CheckedListBox));
            theToolBoxCtrl.AddItem(typeof(RichTextBox));
            theToolBoxCtrl.AddItem(typeof(MonthCalendar));
            theToolBoxCtrl.AddItem(typeof(ProgressBar));
            theToolBoxCtrl.AddItem(typeof(TreeView));
            theToolBoxCtrl.AddItem(typeof(DataGridView));
            theToolBoxCtrl.AddItem(typeof(TrackBar));
            theToolBoxCtrl.AddItem(typeof(HScrollBar));
            theToolBoxCtrl.AddItem(typeof(VScrollBar));
            theToolBoxCtrl.AddItem(typeof(DateTimePicker));
            theToolBoxCtrl.AddItem(typeof(WebBrowser));

            theToolBoxCtrl.AddItem(typeof(StatusStrip));
            theToolBoxCtrl.AddItem(typeof(ToolStrip));
            theToolBoxCtrl.AddItem(typeof(MenuStrip));
            // 初始化树节点，加入树根
            this.theTreeView.Nodes.Add(m_theRootNode);
        }

        /// <summary>
        /// 树节点选择更改之后，Design界面上联动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void theTreeView_AfterSelect(object sender, TreeViewEventArgs e)
        {
            TreeNodeEx node = theTreeView.SelectedNode as TreeNodeEx;
            if (node == m_theRootNode)
            {
                return;
            }
            if (node != null)
            {
                if (node.Parent == m_theRootNode)
                {
                    // 顶级
                    if (node.TheTabPage != null)
                    {
                        this.theTabCtrl.SelectedTab = node.TheTabPage;
                    }
                    FormDesigner theActiveDesigner = ActiveDesigner;
                    ArrayList comps = new ArrayList();
                    theActiveDesigner.Surface.Selections.SetSelectedComponents(comps);
                    comps = null;
                }
                else
                {
                    TreeNodeEx nodeParent = node.Parent as TreeNodeEx;
                    // 子级
                    while (nodeParent.Parent != m_theRootNode)
                    {
                        nodeParent = nodeParent.Parent as TreeNodeEx;
                    }
                    // 找到顶级, 切换到对应的Tab
                    if (nodeParent.TheTabPage != null)
                    {
                        this.theTabCtrl.SelectedTab = nodeParent.TheTabPage;
                    }
                    // 焦点切换
                    FormDesigner theActiveDesigner = ActiveDesigner;
                    ArrayList comps = new ArrayList();
                    comps.Add(node.TheRefCtrl);
                    theActiveDesigner.Surface.Selections.SetSelectedComponents(comps);
                    comps = null;
                }
            }
        }

        private void AddDesigner(FormDesigner.DesignType type, string strName)
        {
            TabPageEx page = new TabPageEx();
            //
            FormDesigner panel = new FormDesigner();
            panel.Dock = DockStyle.Fill;
            page.Controls.Add(panel);
            //
            page.TheFormDesigner = panel;
            page.Text = strName;
            //
            panel.InitSurface(type);
            //
            this.theTabCtrl.Controls.Add(page);
            ControlListService theToolboxService =
                panel.Surface.GetDesignService(typeof(IToolboxService)) as ControlListService;
            theToolboxService.Toolbox = this.theToolBoxCtrl;
            // 切换
            this.theTabCtrl.SelectedTab = page;
            //
            this.thePropertyGrid.SelectedObject = panel;
            panel.Surface.OnSelectionChanged += new EventHandler(Surface_OnSelectionChanged);
            panel.Surface.OnContextMenu += new HookContextMenu(Surface_OnContextMenu);
            panel.Surface.OnComponentAdded += new ComponentEventHandler(Surface_OnComponentAdded);
            panel.Surface.OnComponentRename += new ComponentRenameEventHandler(Surface_OnComponentRename);
            panel.Surface.OnComponentChanged += new ComponentChangedEventHandler(Surface_OnComponentChanged);
            panel.Surface.DesignContainer.KeyUp += new KeyEventHandler(DesignContainer_KeyUp);
            panel.Surface.DesignContainer.KeyDown += new KeyEventHandler(DesignContainer_KeyDown);
            panel.Surface.DesignContainer.BackColor = Color.White;
            // 
            if (type == FormDesigner.DesignType.Form)
            {
                page.ImageIndex = 1;
                page.Text = strName;// "Form";
                TreeNodeEx node = new TreeNodeEx(String.Format("Form [{0}] ", strName), 1, 1);
                node.TheRefCtrl = panel.Surface.RootComponent as Control;
                node.TheTabPage = page;
                this.m_theRootNode.Nodes.Add(node);
            }
            else
            {
                page.ImageIndex = 2;
                page.Text = strName;// "Control";
                TreeNodeEx node = new TreeNodeEx(String.Format("Control [{0}] ", strName), 2, 2);
                node.TheRefCtrl = panel.Surface.RootComponent as Control;
                node.TheTabPage = page;
                this.m_theRootNode.Nodes.Add(node);
            }
            this.m_theRootNode.Expand();
            if (panel.Surface.RootComponent != null)
            {
                panel.Surface.RootComponent.Text = strName;// panel.Surface.RootComponent.GetType().Name;
            }
        }

        /// <summary>
        /// Design界面上追加一个Tab
        /// </summary>
        /// <param name="type"></param>
        private void AddDesigner(FormDesigner.DesignType type)
        {
            SetFormName set = new SetFormName();
            set.DesignerName = type.ToString();//theTabCtrl.TabCount.ToString();
            if (set.ShowDialog() == DialogResult.OK)
            {
                AddDesigner(type, set.DesignerName);
            }
        }

        void DesignContainer_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Up)
            {
                FormDesigner panel = ActiveDesigner;
                if (panel != null)
                {
                    ArrayList comps = new ArrayList();
                    comps.AddRange(panel.Surface.Selections.GetSelectedComponents());
                    if (comps.Count > 0)
                    {
                        foreach (object obj in comps)
                        {
                            Control ctrl = obj as Control;
                            if ((ctrl != null) && (ctrl != panel.Surface.RootComponent))
                            {
                                ctrl.Top--;
                            }
                        }
                        CheckTreeNode(m_theRootNode);
                    }
                }
                this.thePropertyGrid.Refresh();
            }
            else if (e.KeyCode == Keys.Down)
            {
                FormDesigner panel = ActiveDesigner;
                if (panel != null)
                {
                    ArrayList comps = new ArrayList();
                    comps.AddRange(panel.Surface.Selections.GetSelectedComponents());
                    if (comps.Count > 0)
                    {
                        foreach (object obj in comps)
                        {
                            Control ctrl = obj as Control;
                            if ((ctrl != null) && (ctrl != panel.Surface.RootComponent))
                            {
                                ctrl.Top++;
                            }
                        }
                        CheckTreeNode(m_theRootNode);
                    }
                }
                this.thePropertyGrid.Refresh();
            }
            else if (e.KeyCode == Keys.Left)
            {
                FormDesigner panel = ActiveDesigner;
                if (panel != null)
                {
                    ArrayList comps = new ArrayList();
                    comps.AddRange(panel.Surface.Selections.GetSelectedComponents());
                    if (comps.Count > 0)
                    {
                        foreach (object obj in comps)
                        {
                            Control ctrl = obj as Control;
                            if ((ctrl != null) && (ctrl != panel.Surface.RootComponent))
                            {
                                ctrl.Left--;
                            }
                        }
                        CheckTreeNode(m_theRootNode);
                    }
                }
                this.thePropertyGrid.Refresh();
            }
            else if (e.KeyCode == Keys.Right)
            {
                FormDesigner panel = ActiveDesigner;
                if (panel != null)
                {
                    ArrayList comps = new ArrayList();
                    comps.AddRange(panel.Surface.Selections.GetSelectedComponents());
                    if (comps.Count > 0)
                    {
                        foreach (object obj in comps)
                        {
                            Control ctrl = obj as Control;
                            if ((ctrl != null) && (ctrl != panel.Surface.RootComponent))
                            {
                                ctrl.Left++;
                            }
                        }
                        CheckTreeNode(m_theRootNode);
                    }
                }
                this.thePropertyGrid.Refresh();
            }
            else if ((e.KeyCode == Keys.S) && e.Control)
            {
                btn_SaveUI_Click(null, null);
            }
        }

        void DesignContainer_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Delete)
            {
                FormDesigner panel = ActiveDesigner;
                if (panel != null)
                {
                    ArrayList comps = new ArrayList();
                    comps.AddRange(panel.Surface.Selections.GetSelectedComponents());
                    if (comps.Count > 0)
                    {
                        foreach (object obj in comps)
                        {
                            Control ctrl = obj as Control;
                            if ((ctrl != null) && (ctrl != panel.Surface.RootComponent))
                            {
                                panel.Surface.Host.DestroyComponent(ctrl);
                            }
                        }
                        CheckTreeNode(m_theRootNode);
                    }
                    this.thePropertyGrid.Refresh();
                }
            }
        }

        void Surface_OnComponentChanged(object sender, ComponentChangedEventArgs e)
        {
            Control ctrl = e.Component as Control;
            if (ctrl != null)
            {
                ModifyControl(ctrl);
                if (!ctrl.IsDisposed && String.IsNullOrEmpty(ctrl.Text))
                {
                    ctrl.Text = ctrl.GetType().Name;
                }
                CheckTreeNode(m_theRootNode);
                TabControl tab = ctrl as TabControl;
                if (tab != null)
                {
                    foreach (TabPage page in tab.TabPages)
                    {
                        if (page.IsDisposed)
                        {
                            continue;
                        }
                        ModifyControl(page);
                    }
                    TreeNodeEx node = FindTreeNode(m_theRootNode, tab.Handle);
                    if (node != null)
                    {
                        theTreeView.SelectedNode = node;
                    }
                }
                CheckTreeNode(m_theRootNode);
            }
        }

        void Surface_OnComponentRename(object sender, ComponentRenameEventArgs e)
        {
            Control ctrl = e.Component as Control;
            if (ctrl != null)
            {
                ModifyControl(ctrl);
            }
        }

        void Surface_OnComponentAdded(object sender, ComponentEventArgs e)
        {
            Control ctrl = e.Component as Control;
            if (ctrl != null)
            {
                ModifyControl(ctrl);
            }
        }

        /// <summary>
        /// 节点变化
        /// </summary>
        /// <param name="ctrl"></param>
        private void ModifyControl(Control ctrl)
        {
            Type type = ctrl.GetType();
            Image img = theToolBoxCtrl.GetPreviewImage(type);
            int nIndex = -1;
            if (img != null)
            {
                nIndex = m_theImageMgr.Add(type, img);
            }
            TreeNodeEx nodeSelf = FindTreeNode(m_theRootNode, ctrl.Handle);
            TreeNodeEx nodeParent = FindTreeNode(m_theRootNode, WinAPI.GetParent(ctrl.Handle));
            if (ctrl.Parent != null)
            {
                nodeParent = FindTreeNode(m_theRootNode, ctrl.Parent.Handle);
            }
            FormDesigner theActiveDesigner = ActiveDesigner;
            if (nodeSelf == null)
            {
                // Tree上不存在这个节点
                if (nodeParent == null)
                {
                    // 不可能的情况
                }
                else
                {
                    TreeNodeEx node = new TreeNodeEx(type.Name, nIndex, nIndex);
                    node.TheRefCtrl = ctrl;
                    nodeParent.Nodes.Add(node);
                    nodeParent.Expand();
                    theTreeView.SelectedNode = node;
                }
            }
            else if (nodeSelf.Parent != m_theRootNode)
            {
                // Tree上存在这个节点
                // 可能是修改了属性，也可能父节点都变了
                TreeNodeEx theRealParent = nodeSelf.Parent as TreeNodeEx;
                if (theRealParent.TheRefCtrl == nodeParent.TheRefCtrl)
                {
                    // 修改了属性
                }
                else
                {
                    // 父节点变了
                    nodeSelf.Remove();
                    nodeParent.Nodes.Add(nodeSelf);
                    nodeParent.Expand();
                }
                theTreeView.SelectedNode = nodeSelf;
            }
        }

        /// <summary>
        /// 找到特定节点
        /// </summary>
        /// <param name="root"></param>
        /// <param name="theHandle"></param>
        /// <returns></returns>
        private TreeNodeEx FindTreeNode(TreeNodeEx root, IntPtr theHandle)
        {
            if ((theHandle == IntPtr.Zero) || (root == null))
            {
                return null;
            }
            if ((root.TheRefCtrl != null) && !(root.TheRefCtrl.IsDisposed) && (root.TheRefCtrl.Handle == theHandle))
            {
                return root;
            }
            foreach (TreeNodeEx node in root.Nodes)
            {
                if ((node.TheRefCtrl != null) && !(node.TheRefCtrl.IsDisposed) && (node.TheRefCtrl.Handle == theHandle))
                {
                    return node;
                }
                TreeNodeEx find = FindTreeNode(node, theHandle);
                if (find != null)
                {
                    return find;
                }
            }
            return null;
        }

        /// <summary>
        /// 打开定制的右键菜单
        /// </summary>
        /// <param name="ptClient"></param>
        void Surface_OnContextMenu(Point ptClient)
        {
            if (m_theMainContextMenu == null)
            {
                BuildContextMenu();
            }
            FormDesigner panel = ActiveDesigner;
            if (panel != null)
            {
                ArrayList comps = new ArrayList();
                comps.AddRange(panel.Surface.Selections.GetSelectedComponents());
                if (comps.Count == 1)
                {
                }
                else if (comps.Count > 1)
                {
                }
                m_theMainContextMenu.Show(panel, ptClient);
            }
        }

        /// <summary>
        /// 为右键菜单提供命令操作
        /// </summary>
        /// <param name="id"></param>
        private void SurfaceCommand(CommandID id)
        {
            FormDesigner panel = ActiveDesigner;
            if (panel != null)
            {
                panel.Surface.CommandInvoke(id);
            }
        }

        /// <summary>
        /// SurfaceCommand为右键菜单提供命令操作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void HandleSurfaceContextMenu(object sender, EventArgs e)
        {
            MenuItem item = sender as MenuItem;
            if (item != null)
            {
                switch (item.Text)
                {
                    case "左对齐(&L)":
                        SurfaceCommand(StandardCommands.AlignLeft);
                        break;
                    case "居中对齐(&C)":
                        SurfaceCommand(StandardCommands.AlignVerticalCenters);
                        break;
                    case "右对齐(&R)":
                        SurfaceCommand(StandardCommands.AlignRight);
                        break;
                    case "顶端对齐(&S)":
                        SurfaceCommand(StandardCommands.AlignTop);
                        break;
                    case "中间对齐(&M)":
                        SurfaceCommand(StandardCommands.AlignHorizontalCenters);
                        break;
                    case "底端对齐(&B)":
                        SurfaceCommand(StandardCommands.ArrangeBottom);
                        break;
                    case "宽度(&W)":
                        SurfaceCommand(StandardCommands.SizeToControlWidth);
                        break;
                    case "高度(&H)":
                        SurfaceCommand(StandardCommands.SizeToControlHeight);
                        break;
                    case "两者(&B)":
                        SurfaceCommand(StandardCommands.SizeToControl);
                        break;
                    case "相同间隔(&E)":
                        {
                            MenuItem theParent = item.Parent as MenuItem;
                            if (theParent != null)
                            {
                                if (theParent.Text == "水平间距(&H)")
                                {
                                    SurfaceCommand(StandardCommands.HorizSpaceMakeEqual);
                                }
                                else if (theParent.Text == "垂直间距(&V)")
                                {
                                    SurfaceCommand(StandardCommands.VertSpaceMakeEqual);
                                }
                            }
                        }
                        break;
                    case "递增(&I)":
                        {
                            MenuItem theParent = item.Parent as MenuItem;
                            if (theParent != null)
                            {
                                if (theParent.Text == "水平间距(&H)")
                                {
                                    SurfaceCommand(StandardCommands.HorizSpaceIncrease);
                                }
                                else if (theParent.Text == "垂直间距(&V)")
                                {
                                    SurfaceCommand(StandardCommands.VertSpaceIncrease);
                                }
                            }
                        }
                        break;
                    case "递减(&D)":
                        {
                            MenuItem theParent = item.Parent as MenuItem;
                            if (theParent != null)
                            {
                                if (theParent.Text == "水平间距(&H)")
                                {
                                    SurfaceCommand(StandardCommands.HorizSpaceDecrease);
                                }
                                else if (theParent.Text == "垂直间距(&V)")
                                {
                                    SurfaceCommand(StandardCommands.VertSpaceDecrease);
                                }
                            }
                        }
                        break;
                    case "移除(&R)":
                        {
                            MenuItem theParent = item.Parent as MenuItem;
                            if (theParent != null)
                            {
                                if (theParent.Text == "水平间距(&H)")
                                {
                                    SurfaceCommand(StandardCommands.HorizSpaceConcatenate);
                                }
                                else if (theParent.Text == "垂直间距(&V)")
                                {
                                    SurfaceCommand(StandardCommands.VertSpaceConcatenate);
                                }
                            }
                        }
                        break;
                    case "水平对齐(&H)":
                        SurfaceCommand(StandardCommands.CenterHorizontally);
                        break;
                    case "垂直对齐(&V)":
                        SurfaceCommand(StandardCommands.CenterVertically);
                        break;
                    case "置于顶层(&B)":
                        SurfaceCommand(StandardCommands.BringToFront);
                        break;
                    case "置于底层(&S)":
                        SurfaceCommand(StandardCommands.SendToBack);
                        break;
                    case "锁定控件(&L)":
                        SurfaceCommand(StandardCommands.LockControls);
                        break;
                    case "Tab Order(&T)":
                        SurfaceCommand(StandardCommands.TabOrder);
                        break;
                }
            }
        }

        private void BuildContextMenu()
        {
            if (m_theMainContextMenu != null)
            {
                return;
            }
            m_theMainContextMenu = new ContextMenu();
            //
            MenuItem item = new MenuItem("对齐(&A)");
            item.MenuItems.Add("左对齐(&L)", HandleSurfaceContextMenu);
            item.MenuItems.Add("居中对齐(&C)", HandleSurfaceContextMenu);
            item.MenuItems.Add("右对齐(&R)", HandleSurfaceContextMenu);
            item.MenuItems.Add("-");
            item.MenuItems.Add("顶端对齐(&S)", HandleSurfaceContextMenu);
            item.MenuItems.Add("中间对齐(&M)", HandleSurfaceContextMenu);
            item.MenuItems.Add("底端对齐(&B)", HandleSurfaceContextMenu);
            m_theMainContextMenu.MenuItems.Add(item);
            //
            item = new MenuItem("使大小相同(&M)");
            item.MenuItems.Add("宽度(&W)", HandleSurfaceContextMenu);
            item.MenuItems.Add("高度(&H)", HandleSurfaceContextMenu);
            item.MenuItems.Add("两者(&B)", HandleSurfaceContextMenu);
            m_theMainContextMenu.MenuItems.Add(item);
            //
            m_theMainContextMenu.MenuItems.Add("-");
            //
            item = new MenuItem("水平间距(&H)");
            item.MenuItems.Add("相同间隔(&E)", HandleSurfaceContextMenu);
            item.MenuItems.Add("递增(&I)", HandleSurfaceContextMenu);
            item.MenuItems.Add("递减(&D)", HandleSurfaceContextMenu);
            item.MenuItems.Add("移除(&R)", HandleSurfaceContextMenu);
            m_theMainContextMenu.MenuItems.Add(item);
            //
            item = new MenuItem("垂直间距(&V)");
            item.MenuItems.Add("相同间隔(&E)", HandleSurfaceContextMenu);
            item.MenuItems.Add("递增(&I)", HandleSurfaceContextMenu);
            item.MenuItems.Add("递减(&D)", HandleSurfaceContextMenu);
            item.MenuItems.Add("移除(&R)", HandleSurfaceContextMenu);
            m_theMainContextMenu.MenuItems.Add(item);
            //
            m_theMainContextMenu.MenuItems.Add("-");
            //
            item = new MenuItem("在窗体中居中(&C)");
            item.MenuItems.Add("水平对齐(&H)", HandleSurfaceContextMenu);
            item.MenuItems.Add("垂直对齐(&V)", HandleSurfaceContextMenu);
            m_theMainContextMenu.MenuItems.Add(item);
            //
            item = new MenuItem("顺序(&O)");
            item.MenuItems.Add("置于顶层(&B)", HandleSurfaceContextMenu);
            item.MenuItems.Add("置于底层(&S)", HandleSurfaceContextMenu);
            m_theMainContextMenu.MenuItems.Add(item);
            //
            m_theMainContextMenu.MenuItems.Add("-");
            //
            item = new MenuItem("锁定控件(&L)", HandleSurfaceContextMenu);
            m_theMainContextMenu.MenuItems.Add(item);
            //
            m_theMainContextMenu.MenuItems.Add("-");
            //
            item = new MenuItem("Tab Order(&T)", HandleSurfaceContextMenu);
            m_theMainContextMenu.MenuItems.Add(item);
        }

        /// <summary>
        /// DesignView上选择的对象更变，刷新节点树
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void Surface_OnSelectionChanged(object sender, EventArgs e)
        {
            DesignSurfaceEx Surface = sender as DesignSurfaceEx;
            if (Surface != null)
            {
                ArrayList comps = new ArrayList();
                comps.AddRange(Surface.Selections.GetSelectedComponents());
                if (comps.Count == 1)
                {
                    Control ctrl = comps[0] as Control;
                    if (ctrl != null)
                    {
                        TreeNodeEx nodeSelf = FindTreeNode(m_theRootNode, ctrl.Handle);
                        nodeSelf.Parent.Expand();
                        theTreeView.SelectedNode = nodeSelf;
                    }
                }
                else
                {
                    comps.Add(Surface.RootComponent);
                    TreeNodeEx nodeSelf = FindTreeNode(m_theRootNode, Surface.RootComponent.Handle);
                    theTreeView.SelectedNode = nodeSelf;
                }
                this.thePropertyGrid.SelectedObjects = comps.ToArray();
            }
        }

        /// <summary>
        /// 激活节点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void theTreeView_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                TreeNode node = theTreeView.GetNodeAt(e.X, e.Y);
                if (node != null)
                {
                    theTreeView.SelectedNode = node;
                }
            }
        }

        /// <summary>
        /// 获取活动的那个DesignView
        /// </summary>
        private FormDesigner ActiveDesigner
        {
            get
            {
                TabPageEx page = this.theTabCtrl.SelectedTab as TabPageEx;
                if (page != null)
                {
                    FormDesigner panel = page.TheFormDesigner;
                    if (panel != null)
                    {
                        return panel;
                    }
                }
                return null;
            }
        }

        /// <summary>
        /// 检查节点的真实存在性
        /// </summary>
        /// <param name="theParentNode"></param>
        private void CheckTreeNode(TreeNodeEx theParentNode)
        {
            if (theParentNode == null)
            {
                return;
            }
            if ((theParentNode.TheRefCtrl != null)
                && theParentNode.TheRefCtrl.IsDisposed)
            {
                theParentNode.Remove();
            }
            else
            {
                foreach (TreeNodeEx node in theParentNode.Nodes)
                {
                    CheckTreeNode(node);
                }
            }
        }

        /// <summary>
        /// 从树上删除一个节点
        /// </summary>
        private void theTreeView_DeleteSelected()
        {
            TreeNodeEx node = theTreeView.SelectedNode as TreeNodeEx;
            if (node == m_theRootNode)
            {
                return;
            }
            if (node != null)
            {
                //if (MessageBox.Show(
                //    "即将从设计器上移除所有被选中的控件，是否继续?", "警告",
                //    MessageBoxButtons.YesNoCancel,
                //    MessageBoxIcon.Question, 
                //    MessageBoxDefaultButton.Button3) != DialogResult.Yes)
                //{
                //    return;
                //}
                if (node.Parent == m_theRootNode)
                {
                    // 顶级
                    if ((node.TheTabPage != null) && theTabCtrl.Contains(node.TheTabPage))
                    {
                        FormDesigner panel = node.TheTabPage.Controls[0] as FormDesigner;
                        if (panel != null)
                        {
                            panel.Surface.OnSelectionChanged -= new EventHandler(Surface_OnSelectionChanged);
                            panel.Surface.OnContextMenu -= new HookContextMenu(Surface_OnContextMenu);
                            panel.Surface.OnComponentAdded -= new ComponentEventHandler(Surface_OnComponentAdded);
                            panel.Surface.OnComponentRename -= new ComponentRenameEventHandler(Surface_OnComponentRename);
                            panel.Surface.OnComponentChanged -= new ComponentChangedEventHandler(Surface_OnComponentChanged);
                            panel.Surface.DesignContainer.KeyUp -= new KeyEventHandler(DesignContainer_KeyUp);
                            panel.Surface.DesignContainer.KeyDown -= new KeyEventHandler(DesignContainer_KeyDown);
                        }
                        this.theTabCtrl.Controls.Remove(node.TheTabPage);
                    }
                }
                else
                {
                    // 子级
                    if ((node.TheRefCtrl != null) && !node.TheRefCtrl.IsDisposed)
                    {
                        TreeNodeEx nodeParent = node.Parent as TreeNodeEx;
                        // 子级
                        while (nodeParent.Parent != m_theRootNode)
                        {
                            nodeParent = nodeParent.Parent as TreeNodeEx;
                        }
                        // 找到顶级, 切换到对应的Tab
                        if ((nodeParent.TheTabPage != null) && theTabCtrl.Contains(nodeParent.TheTabPage))
                        {
                            FormDesigner panel = nodeParent.TheTabPage.Controls[0] as FormDesigner;
                            if (panel != null)
                            {
                                panel.Surface.Host.DestroyComponent(node.TheRefCtrl);
                            }
                        }
                    }
                }
                node.Remove();
            }
        }

        /// <summary>
        /// 从树上删除一个节点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void theTreeView_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Delete)
            {
                theTreeView_DeleteSelected();
            }
        }

        /// <summary>
        /// 追加一个DesignView
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_NewForm_Click(object sender, EventArgs e)
        {
            AddDesigner(FormDesigner.DesignType.Form);
        }

        /// <summary>
        /// 追加一个DesignView
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_NewUserControl_Click(object sender, EventArgs e)
        {
            AddDesigner(FormDesigner.DesignType.Control);
        }

        /// <summary>
        /// 从树上删除一个节点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_DeleteNode_Click(object sender, EventArgs e)
        {
            theTreeView_DeleteSelected();
        }

        private void btn_OpenUI_Click(object sender, EventArgs e)
        {

        }

        private void btn_SaveUI_Click(object sender, EventArgs e)
        {
            // Save 
            TabPageEx page = this.theTabCtrl.SelectedTab as TabPageEx;
            if (page == null)
            {
                return;
            }
            if (String.IsNullOrEmpty(page.TheFilePath))
            {
                SaveFileDialog dlg = new SaveFileDialog();
                dlg.AddExtension = true;
                dlg.DefaultExt = ".vui";
                dlg.OverwritePrompt = true;
                dlg.Title = "选择文件保存位置";
                dlg.SupportMultiDottedExtensions = true;
                dlg.ValidateNames = true;
                dlg.Filter = " GUI 模型(*.vui)|*.vui";
                if (dlg.ShowDialog() == DialogResult.OK)
                {
                    page.TheFilePath = dlg.FileName;
                }
                else
                {
                    return;
                }
            }
            try
            {
                Control theRootComponent = page.TheFormDesigner.Surface.RootComponent;
                XmlDocument xmlDoc = new XmlDocument();
                XmlElement elem = xmlDoc.CreateElement(theRootComponent.GetType().Name);
                xmlDoc.AppendChild(elem);
                AppendAttributeAndChild(xmlDoc, elem, theRootComponent);
                xmlDoc.Save(page.TheFilePath);
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void AddFormToXml(XmlDocument xmlDoc, XmlElement node, Form theForm)
        {
            XmlAttribute attr = xmlDoc.CreateAttribute("BorderStyle");
            node.Attributes.Append(attr);
            switch (theForm.FormBorderStyle)
            {
                case FormBorderStyle.Fixed3D:
                    attr.Value = "Fixed3D";
                    break;
                case FormBorderStyle.FixedDialog:
                    attr.Value = "FixedDialog";
                    break;
                case FormBorderStyle.FixedSingle:
                    attr.Value = "FixedSingle";
                    break;
                case FormBorderStyle.FixedToolWindow:
                    attr.Value = "FixedToolWindow";
                    break;
                case FormBorderStyle.None:
                    attr.Value = "None";
                    break;
                case FormBorderStyle.Sizable:
                    attr.Value = "Sizable";
                    break;
                case FormBorderStyle.SizableToolWindow:
                    attr.Value = "SizableToolWindow";
                    break;
                default:
                    attr.Value = "Sizable";
                    break;
            }
            // 大小
            attr = xmlDoc.CreateAttribute("Width");
            node.Attributes.Append(attr);
            attr.Value = theForm.Width.ToString();
            attr = xmlDoc.CreateAttribute("Height");
            node.Attributes.Append(attr);
            attr.Value = theForm.Height.ToString();
            // 名称
            //attr = xmlDoc.CreateAttribute("Name");
            //node.Attributes.Append(attr);
            //attr.Value = theForm.Name.ToString();
            attr = xmlDoc.CreateAttribute("Text");
            node.Attributes.Append(attr);
            attr.Value = theForm.Text.ToString();
            // 背景
            attr = xmlDoc.CreateAttribute("BackColor");
            node.Attributes.Append(attr);
            attr.Value = String.Format("0x{0:X8}", theForm.BackColor.ToArgb());
            // ControlBox
            attr = xmlDoc.CreateAttribute("ControlBox");
            node.Attributes.Append(attr);
            attr.Value = theForm.ControlBox.ToString();
            // MaximizeBox
            attr = xmlDoc.CreateAttribute("MaximizeBox");
            node.Attributes.Append(attr);
            attr.Value = theForm.MaximizeBox.ToString();
            // MinimizeBox
            attr = xmlDoc.CreateAttribute("MinimizeBox");
            node.Attributes.Append(attr);
            attr.Value = theForm.MinimizeBox.ToString();
            // TopMost
            attr = xmlDoc.CreateAttribute("TopMost");
            node.Attributes.Append(attr);
            attr.Value = theForm.TopMost.ToString();
            // TransparencyKey
            if (theForm.TransparencyKey != Color.Empty)
            {
                attr = xmlDoc.CreateAttribute("TransparencyKey");
                node.Attributes.Append(attr);
                attr.Value = String.Format("0x{0:X8}", theForm.TransparencyKey.ToArgb());
            }
        }

        private void AppendToolStripItemToXml(XmlDocument xmlDoc, XmlElement node, ToolStripItem theItem)
        {
            // Add Self
            XmlAttribute attr = null;
            attr = xmlDoc.CreateAttribute("Text");
            node.Attributes.Append(attr);
            attr.Value = theItem.Text.ToString();
            attr = xmlDoc.CreateAttribute("CanSelect");
            node.Attributes.Append(attr);
            attr.Value = theItem.CanSelect.ToString();
            attr = xmlDoc.CreateAttribute("Enabled");
            node.Attributes.Append(attr);
            attr.Value = theItem.Enabled.ToString();
            //attr = xmlDoc.CreateAttribute("Name");
            //node.Attributes.Append(attr);
            //attr.Value = theItem.Name.ToString();
            attr = xmlDoc.CreateAttribute("Selected");
            node.Attributes.Append(attr);
            attr.Value = theItem.Selected.ToString();
            // Add Child
            if (theItem is ToolStripDropDownItem)
            {
                if (theItem is ToolStripDropDownButton)
                {
                    ToolStripDropDownButton theButton = theItem as ToolStripDropDownButton;
                    attr = xmlDoc.CreateAttribute("ShowDropDownArrow");
                    node.Attributes.Append(attr);
                    attr.Value = theButton.ShowDropDownArrow.ToString();
                }
                ToolStripDropDownItem theMenuItem = theItem as ToolStripDropDownItem;
                for (int i = 0; i < theMenuItem.DropDownItems.Count - 1; i++ )
                {
                    ToolStripItem child = theMenuItem.DropDownItems[i] as ToolStripItem;
                    XmlElement elemChild = xmlDoc.CreateElement(child.GetType().Name);
                    node.AppendChild(elemChild);
                    AppendToolStripItemToXml(xmlDoc, elemChild, child);
                }
            }
        }

        private void AddMenuStripToXml(XmlDocument xmlDoc, XmlElement node, MenuStrip theMenuStrip)
        {
            // Add Self
            XmlAttribute attr = null;
            attr = xmlDoc.CreateAttribute("ForeColor");
            node.Attributes.Append(attr);
            attr.Value = String.Format("0x{0:X8}", theMenuStrip.ForeColor.ToArgb());
            attr = xmlDoc.CreateAttribute("FontName");
            node.Attributes.Append(attr);
            attr.Value = theMenuStrip.Font.Name.ToString();
            attr = xmlDoc.CreateAttribute("FontSize");
            node.Attributes.Append(attr);
            attr.Value = theMenuStrip.Font.Size.ToString();
            attr = xmlDoc.CreateAttribute("BackColor");
            node.Attributes.Append(attr);
            attr.Value = String.Format("0x{0:X8}", theMenuStrip.BackColor.ToArgb());
            node.Attributes.Append(attr);
            attr.Value = String.Format("0x{0:X8}", theMenuStrip.BackColor.ToArgb());
            // Add Child
            foreach (ToolStripItem child in theMenuStrip.Items)
            {
                if ("DesignerToolStripControlHost" != child.GetType().Name)
                {
                    XmlElement elemChild = xmlDoc.CreateElement(child.GetType().Name);
                    node.AppendChild(elemChild);
                    AppendToolStripItemToXml(xmlDoc, elemChild, child);
                }
            }
        }

        private void AddToolStripToXml(XmlDocument xmlDoc, XmlElement node, ToolStrip theToolStrip)
        {
            // Add Self
            // ...
            // Add Child
            foreach (ToolStripItem child in theToolStrip.Items)
            {
                if ("DesignerToolStripControlHost" != child.GetType().Name)
                {
                    XmlElement elemChild = xmlDoc.CreateElement(child.GetType().Name);
                    node.AppendChild(elemChild);
                    AppendToolStripItemToXml(xmlDoc, elemChild, child);
                }
            }
        }

        private void AddStatusStripToXml(XmlDocument xmlDoc, XmlElement node, StatusStrip theStatusStrip)
        {
            // Add Self
            // ...
            // Add Child
            foreach (ToolStripItem child in theStatusStrip.Items)
            {
                if ("DesignerToolStripControlHost" != child.GetType().Name)
                {
                    XmlElement elemChild = xmlDoc.CreateElement(child.GetType().Name);
                    node.AppendChild(elemChild);
                    AppendToolStripItemToXml(xmlDoc, elemChild, child);
                }
            }
        }

        private void AppendAttributeAndChild(XmlDocument xmlDoc, XmlElement node, Control theComponent)
        {
            if (theComponent is Form)
            {
                AddFormToXml(xmlDoc, node, theComponent as Form);
            }
            else if (theComponent is MenuStrip)
            {
                AddMenuStripToXml(xmlDoc, node, theComponent as MenuStrip);
                return;
            }
            else if (theComponent is ToolStrip)
            {
                AddToolStripToXml(xmlDoc, node, theComponent as ToolStrip);
                return;
            }
            else if (theComponent is StatusStrip)
            {
                AddStatusStripToXml(xmlDoc, node, theComponent as StatusStrip);
                return;
            }
            else
            {
                /*
                 * 大小
                 * 位置
                 * 名称
                 * 边框
                 * 字体
                 * 背景
                 * 可用性
                 * TabIndex
                 * */
                XmlAttribute attr = null;
                // 大小
                attr = xmlDoc.CreateAttribute("Width");
                node.Attributes.Append(attr);
                attr.Value = theComponent.Width.ToString();
                attr = xmlDoc.CreateAttribute("Height");
                node.Attributes.Append(attr);
                attr.Value = theComponent.Height.ToString();
                // 位置
                attr = xmlDoc.CreateAttribute("X");
                node.Attributes.Append(attr);
                attr.Value = theComponent.Left.ToString();
                attr = xmlDoc.CreateAttribute("Y");
                node.Attributes.Append(attr);
                attr.Value = theComponent.Top.ToString();
                // 名称
                //attr = xmlDoc.CreateAttribute("Name");
                //node.Attributes.Append(attr);
                //attr.Value = theComponent.Name.ToString();
                attr = xmlDoc.CreateAttribute("Text");
                node.Attributes.Append(attr);
                attr.Value = theComponent.Text.ToString();
                // 字体
                attr = xmlDoc.CreateAttribute("FontName");
                node.Attributes.Append(attr);
                attr.Value = theComponent.Font.Name.ToString();
                attr = xmlDoc.CreateAttribute("FontBold");
                node.Attributes.Append(attr);
                attr.Value = theComponent.Font.Bold.ToString();
                attr = xmlDoc.CreateAttribute("FontItalic");
                node.Attributes.Append(attr);
                attr.Value = theComponent.Font.Italic.ToString();
                attr = xmlDoc.CreateAttribute("FontUnderline");
                node.Attributes.Append(attr);
                attr.Value = theComponent.Font.Underline.ToString();
                attr = xmlDoc.CreateAttribute("FontSize");
                node.Attributes.Append(attr);
                attr.Value = theComponent.Font.Size.ToString();
                attr = xmlDoc.CreateAttribute("FontColor");
                node.Attributes.Append(attr);
                attr.Value = String.Format("0x{0:X8}", theComponent.ForeColor.ToArgb());
                // 背景
                attr = xmlDoc.CreateAttribute("BackColor");
                node.Attributes.Append(attr);
                attr.Value = String.Format("0x{0:X8}", theComponent.BackColor.ToArgb());
                // 可用性
                attr = xmlDoc.CreateAttribute("Enabled");
                node.Attributes.Append(attr);
                attr.Value = theComponent.Enabled.ToString();
                // TabIndex
                attr = xmlDoc.CreateAttribute("TabIndex");
                node.Attributes.Append(attr);
                attr.Value = theComponent.TabIndex.ToString();
            }
            foreach (Control child in theComponent.Controls)
            {
                XmlElement elemChild = xmlDoc.CreateElement(child.GetType().Name);
                node.AppendChild(elemChild);
                AppendAttributeAndChild(xmlDoc, elemChild, child);
            }
        }
    }
}
